//
//  cwRadioAppDelegate.m
//  cwRadio
//
//  Created by Niels Buekers on 12/11/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "cwRadioAppDelegate.h"
#import "GCDAsyncSocket.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "TBXML.h"
#import "songDetails.h"
#import "playlistViewController.h"
#import "groupViewController.h"



//static const int ddLogLevel = LOG_LEVEL_ERROR;


@implementation cwRadioAppDelegate

@synthesize window;
@synthesize tabBarController;

#pragma mark -
#pragma mark Application lifecycle


- (void)normalConnect:(NSString*)ip
{
	NSError *error = nil;
	if (![asyncSocket connectToHost:ip onPort:5000 error:&error])
	{
		NSLog(@"Error connecting: %@", error);
	}
}

- (void)secureConnect
{
	NSError *error = nil;
	if (![asyncSocket connectToHost:@"www.paypal.com" onPort:443 error:&error])
	{
		NSLog(@"Error connecting: %@", error);
	}
}


- (void) playSong{
	AVPlayerItem *it;
	if(listOfSong==nil){
		it = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://stream10.jamendo.com/stream/109534/mp31/12%20-%20Don%20Vincenzoo%20-%20le%20mal%20envahie.mp3"]] retain];	
	}else {
		it = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[listOfSong objectAtIndex:0] getStream] ]]  retain];
	}
	[player replaceCurrentItemWithPlayerItem:it];
	
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{
	[self normalConnect:[[alertView textField] text]];	
}



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
	UIAlertView *insertScore = [UIAlertView new];
	[insertScore setDelegate:self];
	[insertScore setTitle:@"Music Server:"];
	[insertScore addButtonWithTitle:@"Ok"];
	
	[insertScore addTextFieldWithValue:@"10.8.32.25" label:@"serverip"];
	
	[[insertScore textField] setDelegate:self];
	
	[insertScore show];     
	
	[insertScore release];
	
	[(playlistViewController*)[[tabBarController viewControllers] objectAtIndex:1]init] ;
    // Override point for customization after application launch.
	
	dispatch_queue_t mainQueue = dispatch_get_main_queue();
	asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];
	NSData* aData;
	aData= [@"</data>" dataUsingEncoding: NSASCIIStringEncoding];
	[asyncSocket readDataToData:aData withTimeout:10000 tag:100];
    // Add the tab bar controller's view to the window and display.
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];
	if(listOfSong==nil){
		player = [[AVPlayer playerWithURL:[NSURL URLWithString:@"http://stream10.jamendo.com/stream/109534/mp31/12%20-%20Don%20Vincenzoo%20-%20le%20mal%20envahie.mp3"]] retain];	
	}else {
		player = [[AVPlayer playerWithURL:[NSURL URLWithString:[[listOfSong objectAtIndex:0] getStream] ]]  retain];
	}

	[player play];
	//fill in standard group data
	NSMutableArray* lijst = [[NSMutableArray alloc] init];
	[lijst addObject:@"Determining location..."];
	//[(groupViewController*)[[tabBarController viewControllers] objectAtIndex:2]init];
	[(groupViewController*)[[tabBarController viewControllers] objectAtIndex:2] setGroups:lijst];
	//only when no server is running
	//[self parseData:nil];
	return YES;
}

-(void) locationUpdate:(CLLocation*)location{
	NSString *text = @"<data><login x=\"";
	text = [text stringByAppendingString:[NSString stringWithFormat:@"%f",location.coordinate.latitude]];
	text = [text stringByAppendingString:@"\" y=\""];
	text = [text stringByAppendingString:[NSString stringWithFormat:@"%f",location.coordinate.longitude]];
	text = [text stringByAppendingString:@"\"/></data>"];
	NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
	[asyncSocket writeData:data withTimeout:10 tag:100];
	NSLog(@"write location to groupserver");
}

-(void) locationError:(NSError *)error{
	NSString *text = @"<data><login/></data>";
	NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
	[asyncSocket writeData:data withTimeout:10 tag:100];
	NSLog(@"write to groupserver");
}

-(void) joinGroup:(NSString*)groep{
	NSString *text = @"<data><join>";
	if(groep != nil)
		text = [text stringByAppendingString:groep];
	text = [text stringByAppendingString:@"</join></data>"];
	
	NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
	
	[asyncSocket writeData:data withTimeout:10 tag:100];	
}

-(void) voteGenre:(NSString *)g{
	NSString *text = @"<data><vote>";
	text = [text stringByAppendingString:g];
	text = [text stringByAppendingString:@"</vote></data>"];

	NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
	
	[asyncSocket writeData:data withTimeout:10 tag:100];
}

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
	NSString* aStr;
	aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
	NSLog(@"XML ontvangen %@\n\n\n\n",aStr);
	[self parseData:aStr];
	//data has been read, reaend new data
	[self playSong];
	NSData* aData;
	aData= [@"</data>" dataUsingEncoding: NSASCIIStringEncoding];
	[asyncSocket readDataToData:aData withTimeout:10000 tag:100];
	
	
}

-(void) parseData:(NSString*) data{
	//parsing the xml
	TBXML* tbxml = [[TBXML tbxmlWithXMLString:data] retain];
	//Here starts the reading from the parsed xml
	TBXMLElement *root = [tbxml rootXMLElement];
	if(root!=nil){
		//findout wich type we just parsed and call the dedicated function
		TBXMLElement *type= [TBXML childElementNamed:@"current" parentElement:root];
		if(type != nil){
			[self parseNewPlaylist: root firstTrack: type];
			return;
		}
		type= [TBXML childElementNamed:@"group" parentElement:root];
		if(type!=nil)
		{
			[self parseNewGrouplist: root firstGroup: type];
			return;
		}
		type= [TBXML childElementNamed:@"track" parentElement:root];
		if(type!=nil)
		{
			[self parseNewTracklist: root firstTrack: type];
			return;
		}				
	}
	[tbxml release];
}

-(void) parseNewPlaylist:(TBXMLElement*) root firstTrack:(TBXMLElement*) track {
	//read all elements from every track and add them
	NSMutableArray* pl= [[NSMutableArray alloc] init];
	TBXMLElement * _id=[TBXML childElementNamed:@"id" parentElement:track];
	TBXMLElement * _name = [TBXML childElementNamed:@"name" parentElement:track];
	TBXMLElement * url= [TBXML childElementNamed:@"url" parentElement:track];
	TBXMLElement * stream= [TBXML childElementNamed:@"stream" parentElement:track];
	TBXMLElement * genre= [TBXML childElementNamed:@"tag_idstr" parentElement:track];
	TBXMLElement * duration= [TBXML childElementNamed:@"duration" parentElement:track];
	TBXMLElement * coverUrl= [TBXML childElementNamed:@"album_image" parentElement:track];
	TBXMLElement * album_name= [TBXML childElementNamed:@"album_name" parentElement:track];
	TBXMLElement * artist_name= [TBXML childElementNamed:@"artist_name" parentElement:track];
	songDetails* sd= [[[songDetails alloc]initWithArtist:[TBXML textForElement:artist_name]		
												   title: [TBXML textForElement:_name] 
												   album:[TBXML textForElement:album_name]
												   coverUrl:[TBXML textForElement:coverUrl]
												   genre: [self getGenrenr:[TBXML textForElement:genre]]
													 url: [TBXML textForElement:url]				
												  stream: [TBXML textForElement:stream] 
													 _id:[[TBXML textForElement:_id]intValue]	
												duration:[[TBXML textForElement:duration]intValue]]retain];
	[pl addObject:sd];
	track = [TBXML childElementNamed:@"track" parentElement:root];
	//going trough the rest of the tracks, dynamic list
	while(track!=nil){
		TBXMLElement * _id=[TBXML childElementNamed:@"id" parentElement:track];
		TBXMLElement * _name = [TBXML childElementNamed:@"name" parentElement:track];
		TBXMLElement * url= [TBXML childElementNamed:@"url" parentElement:track];
		TBXMLElement * genre= [TBXML childElementNamed:@"tag_idstr" parentElement:track];
		TBXMLElement * coverUrl= [TBXML childElementNamed:@"album_image" parentElement:track];
		TBXMLElement * stream= [TBXML childElementNamed:@"stream" parentElement:track];
		TBXMLElement * duration= [TBXML childElementNamed:@"duration" parentElement:track];
		TBXMLElement * album_name= [TBXML childElementNamed:@"album_name" parentElement:track];
		TBXMLElement * artist_name= [TBXML childElementNamed:@"artist_name" parentElement:track];
		songDetails* sd=[[songDetails alloc]initWithArtist:[TBXML textForElement:artist_name] 
													 title: [TBXML textForElement:_name]
													 album: [TBXML textForElement:album_name]
													coverUrl:[TBXML textForElement:coverUrl]
													 genre: [self getGenrenr:[TBXML textForElement:genre]]
													   url: [TBXML textForElement:url]
													stream: [TBXML textForElement:stream] 
													   _id:[[TBXML textForElement:_id]intValue]
												  duration:[[TBXML textForElement:duration]intValue]];
		[pl addObject:sd];
		track=[TBXML nextSiblingNamed:@"track" searchFromElement:track];	
	}
	[(playlistViewController*)[[tabBarController viewControllers] objectAtIndex:1]setPlaylist:pl ];
	[self playSong ];
}

-(void) parseNewGrouplist:(TBXMLElement*) root firstGroup:(TBXMLElement*)group {
	NSMutableArray* groups=[[NSMutableArray alloc] init];
	//going through through the groups, dynamic list
	while (group!=nil) {
		TBXMLElement* name= [TBXML childElementNamed:@"name" parentElement:group];
		[groups addObject: [TBXML textForElement:name]];
		group=[TBXML nextSiblingNamed:@"group" searchFromElement:group];
	}
	[(groupViewController*)[[tabBarController viewControllers] objectAtIndex:2]setGroups:groups];
}

//unused in the final version, this function supports functionality for only replacing the tail of the playlist
//f.e. when a song would receive many negative votes the server could send a new playlist without changing the track
-(void) parseNewTracklist:(TBXMLElement*) root firstTrack:(TBXMLElement*) track{
	NSMutableArray* pl= [[NSMutableArray alloc] init];
	while(track!=nil){
		TBXMLElement * _id=[TBXML childElementNamed:@"id" parentElement:track];
		TBXMLElement * _name = [TBXML childElementNamed:@"name" parentElement:track];
		TBXMLElement * url= [TBXML childElementNamed:@"url" parentElement:track];
		TBXMLElement * coverUrl= [TBXML childElementNamed:@"album_image" parentElement:track];
		TBXMLElement * genre= [TBXML childElementNamed:@"tag_idstr" parentElement:track];
		TBXMLElement * stream= [TBXML childElementNamed:@"stream" parentElement:track];
		TBXMLElement * duration= [TBXML childElementNamed:@"duration" parentElement:track];
		TBXMLElement * album_name= [TBXML childElementNamed:@"album_name" parentElement:track];
		TBXMLElement * artist_name= [TBXML childElementNamed:@"artist_name" parentElement:track];
		songDetails* sd=[[songDetails alloc]initWithArtist:[TBXML textForElement:artist_name] 
													 title: [TBXML textForElement:_name]
													 album: [TBXML textForElement:album_name]
													 coverUrl:[TBXML textForElement:coverUrl]
													 genre: [self getGenrenr:[TBXML textForElement:genre]]
													   url: [TBXML textForElement:url]
													stream: [TBXML textForElement:stream] 
													   _id:[[TBXML textForElement:_id]intValue]
												  duration:[[TBXML textForElement:duration]intValue]];
		[pl addObject:sd];
		track=[TBXML nextSiblingNamed:@"track" searchFromElement:track];	
	}
	[(playlistViewController*)[[tabBarController viewControllers] objectAtIndex:1]updatePlaylist:pl ];
}

//a help-function
-(NSInteger) getGenrenr:(NSString*)str{
	if( [str isEqualToString:@"rock"])
		return rock;
	else if ([str isEqualToString:@"metal"])
		return metal;
	else if ([str isEqualToString:@"classic"])
		return classic;
	else if ([str isEqualToString:@"soundtrack"])
		return soundtrack;
	else if ([str isEqualToString:@"reggae"])
		return reggae;
	else if ([str isEqualToString:@"hiphop"])
		return hiphop;
	else 
		return 0;
}

//functions for managing the connection
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
	NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
	if (port == 443)
	{
		// Configure SSL/TLS settings
		NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:3];
		//a connection 
		[settings setObject:@"www.paypal.com"
					 forKey:(NSString *)kCFStreamSSLPeerName];
		
		NSLog(@"Starting TLS with settings:\n%@", settings);
		
		[sock startTLS:settings];
	}
}

- (void)socketDidSecure:(GCDAsyncSocket *)sock
{
	NSLog(@"socketDidSecure:%p", sock);
}

//lifecycle events as with android, the current behavoir was satisfying so we did not change this
- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}


- (void)applicationWillTerminate:(UIApplication *)application {
    /*
     Called when the application is about to terminate.
     See also applicationDidEnterBackground:.
     */
}


#pragma mark -
#pragma mark UITabBarControllerDelegate methods

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
}
*/

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed {
}
*/


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}


- (void)dealloc {
    [tabBarController release];
    [window release];
    [super dealloc];
}

@end

